using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using PasteFormHelper;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace OpenPasteSpider.projectmodel
{

    /// <summary>
    /// 应用
    ///</summary>
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
    public class ServiceInfoAppService : UserAppService
    {

        private IOpenPasteSpiderDbContext _dbContext;
        private readonly PublicModelHelper _modelHelper;
        private readonly ILogger<ServiceInfoAppService> _logger;

        private readonly SpiderConfig _config;

        //public ServiceInfoAppService(
        //    IOpenPasteSpiderDbContext dbContext,
        //    ModelCacheHelper modelHelper,
        //    IOptions<SpiderConfig> config,
        //    ILogger<ServiceInfoAppService> logger)
        //{
        //    _dbContext = dbContext;
        //    _modelHelper = modelHelper;
        //    _logger = logger;
        //    _config = config.Value;
        //}

        public ServiceInfoAppService(IOpenPasteSpiderDbContext dbContext,
            PublicModelHelper modelHelper,
            IOptions<SpiderConfig> config,
            ILogger<ServiceInfoAppService> logger, 
            IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
        {
            _dbContext = dbContext;
            _modelHelper = modelHelper;
            _logger = logger;
            _config = config.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PagedResultDto<ServiceInfoListDto>> GetListAsync(int page = 1, int size = 20)
        {
            var query = _dbContext.ServiceInfo.Where(t => 1 == 1).Include(x => x.Project).OrderByDescending(xy => xy.Id);
            var pagedResultDto = new PagedResultDto<ServiceInfoListDto>();
            pagedResultDto.TotalCount = await query.CountAsync();
            var userList = await query.Page(page, size).ToListAsync();
            var temList = ObjectMapper.Map<List<ServiceInfo>, List<ServiceInfoListDto>>(userList);
            pagedResultDto.Items = temList;
            return pagedResultDto;
        }

        ///// <summary>
        ///// 读取我的可用列表 用于PC文件同步
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //[HttpPost]
        //public async Task<PagedResultDto<ServiceInfoListDto>> ReadForUpload(InputSearch input)
        //{
        //    //读取我可用的列表 ，然后读取可用的列表

        //    //先要进行权限的校验，是否有软件的使用权限 time_token

        //    //time__modelHelper._SignToken_usertoken
        //    var userid = base.ReadLoginUserId();

        //    //md5:time_[code]_{sign} tosign

        //    if (String.IsNullOrEmpty(_config.SyncSoftToken))
        //    {
        //        throw new PasteException("当前系统没有本软件的使用权限，请到官网购买!");
        //    }

        //    if (_config.SyncSoftToken.IndexOf("_") > 0)
        //    {
        //        var now = DateTime.Now.ToUnixTimeSeconds();
        //        var strs = _config.SyncSoftToken.Split('_');
        //        long.TryParse(strs[0],out var tt);
        //        if (now > tt)
        //        {
        //            throw new PasteException("软件使用权限到期，请重新从官网重新购买后重新打包运行!");
        //        }
        //        if (strs[1] != $"{tt}_{_modelHelper.GuidCode}_{_config.UserToken}".ToMd5Lower())
        //        {
        //            throw new PasteException("软件密钥格式有误，请重新从官网打包后重新运行!");
        //        }
        //    }
        //    else
        //    {
        //        //Console.WriteLine("SyncToken:"+_config.SyncSoftToken);
        //        throw new PasteException("软件密钥格式有误，请重新从官网打包后重新运行!");
        //    }

        //    var query = _dbContext.ServiceInfo.Where(t => t.IsEnable).WhereIf(!String.IsNullOrEmpty(input.Word), x => x.Name.Contains(input.Word) || x.Code.Contains(input.Word));
        //    //判断是读取所有的服务，还是读取有权限的服务

            


        //    var pagedResultDto = new PagedResultDto<ServiceInfoListDto>();
        //    pagedResultDto.TotalCount = await query.CountAsync();
        //    var userList = await query.Include(x=>x.Project).OrderByDescending(x=>x.Project.Id).Page(input.page, input.size).ToListAsync();
        //    var temList = ObjectMapper.Map<List<ServiceInfo>, List<ServiceInfoListDto>>(userList);
        //    pagedResultDto.Items = temList;
        //    return pagedResultDto;
        //}

        /// <summary>
        /// 根据ID获取单项应用
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ServiceInfoDto GetByIdAsync(int id)
        {
            var query = _dbContext.ServiceInfo.Where(t => t.Id == id).Include(x => x.Project).FirstOrDefault();
            var temList = ObjectMapper.Map<ServiceInfo, ServiceInfoDto>(query);
            return temList;
        }

        /// <summary>
        /// 根据ID获取待更新单项信息应用
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ServiceInfoUpdateDto GetInfoForUpdateAsync(int id)
        {
            var query = _dbContext.ServiceInfo.Where(t => t.Id == id).Include(x => x.Project).FirstOrDefault();
            var temList = ObjectMapper.Map<ServiceInfo, ServiceInfoUpdateDto>(query);
            temList.ProjectId = query.Project.Id; 
            return temList;
        }


        /// <summary>
        /// 添加一个应用
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ServiceInfoDto> CreateItemAsync(ServiceInfoAddDto input)
        {

            var newu = ObjectMapper.Map<ServiceInfoAddDto, ServiceInfo>(input);
            newu.IsEnable = true; 
            if (input.ProjectId != 0)
            {
                var _mtypeproject = await _dbContext.ProjectInfo.Where(x => x.Id == input.ProjectId).FirstOrDefaultAsync();
                if (_mtypeproject == null || _mtypeproject == default)
                {
                    throw new UserFriendlyException("类型不存在，请确认!");
                }
                newu.Project = _mtypeproject;
                //newu.ImagePrefix = $"{_mtypeproject.Code}_{input.Code}";
            }//添加自定义

            if (!String.IsNullOrEmpty(input.DirectPath))
            {
                if (!input.DirectPath.StartsWith("/"))
                {
                    throw new PasteCodeException("直接存放路径需要/开头，非/结尾，路径是相对于app内来说的！因该是/spider/开头");
                }
                if (input.DirectPath.EndsWith("/"))
                {
                    throw new PasteCodeException("直接存放路径，非/结尾，请去除最末尾的/后再试！");
                }
            }

            _dbContext.Database.BeginTransaction();
            try
            {
                _dbContext.Add(newu);
                await _dbContext.SaveChangesAsync();

                if (input.models != null && input.models.Length > 0)
                {
                    foreach (var ii in input.models)
                    {
                        //创建默认模型
                        var _model = new ModelInfo();
                        _model.Code = ii;
                        _model.Desc = "";
                        _model.ProjectId = newu.Project != null ? newu.Project.Id : 0;
                        _model.Service = newu;
                        _dbContext.Add(_model);
                    }
                }
                await _dbContext.SaveChangesAsync();
                _dbContext.Database.CommitTransaction();
            }
            catch (Exception exl)
            {
                _dbContext.Database.RollbackTransaction();
                _logger.LogException(exl);
            }
            //var updated = await _repository.InsertAsync(newu,true);
            var backinfo = ObjectMapper.Map<ServiceInfo, ServiceInfoDto>(newu);
            return backinfo;
        }
        /// <summary>
        /// 更新一个应用
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ServiceInfoDto> UpdateItemAsync(ServiceInfoUpdateDto input)
        {
            if (!String.IsNullOrEmpty(input.DirectPath))
            {
                if (!input.DirectPath.StartsWith("/"))
                {
                    throw new PasteCodeException("直接存放路径需要/开头，非/结尾，路径是相对于app内来说的！因该是/spider/开头");
                }
                if (input.DirectPath.EndsWith("/"))
                {
                    throw new PasteCodeException("直接存放路径，非/结尾，请去除最末尾的/后再试！");
                }
            }

            var info = await _dbContext.ServiceInfo.Where(x => x.Id == input.Id).Include(x => x.Project).FirstOrDefaultAsync();
            if (info == null || info == default)
            {
                throw new UserFriendlyException("需要查询的信息不存在", "404");
            }
            ObjectMapper.Map<ServiceInfoUpdateDto, ServiceInfo>(input, info);
            if (input.ProjectId != 0)
            {
                if (info.Project == null || input.ProjectId != info.Project.Id)
                {
                    var _mtypeproject = await _dbContext.ProjectInfo.Where(x => x.Id == input.ProjectId).FirstOrDefaultAsync();
                    if (_mtypeproject == null || _mtypeproject == default)
                    {
                        throw new UserFriendlyException("项目信息不存在，请确认!");
                    }
                    info.Project = _mtypeproject;
                    //info.ImagePrefix = $"{_mtypeproject.Code}_{input.Code}";
                }
                //else
                //{
                //    var prodto = await _modelHelper.ItemProjectInfo(input.ProjectId, _dbContext);
                //    if (prodto != null && prodto != default)
                //    {
                //        info.ImagePrefix = $"{prodto.Code}_{input.Code}";
                //    }
                //}
            }            //var updated = await _repository.UpdateAsync(newu);
            await _dbContext.SaveChangesAsync();
            var backinfo = ObjectMapper.Map<ServiceInfo, ServiceInfoDto>(info);
            await _modelHelper.ItemServiceClean(input.Id);
            return backinfo;
        }
        
        /// <summary>
        /// 读取AddDto的数据模型 用于新增
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public VoloModelInfo ReadAddModel()
        {
            var _model = PasteBuilderHelper.ReadModelProperty<ServiceInfoAddDto>(new ServiceInfoAddDto());
            return _model;
        }

        /// <summary>
        /// 读取Dto的数据模型 用于更新
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<VoloModelInfo> ReadUpdateModel(int id)
        {
            var _info = await _dbContext.ServiceInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();
            if (_info == null || _info == default)
            {
                throw new PasteCodeException("查询的信息不存在，无法执行编辑操作！");
            }
            var dto = ObjectMapper.Map<ServiceInfo, ServiceInfoUpdateDto>(_info);
            var _dataModel = PasteBuilderHelper.ReadModelProperty<ServiceInfoUpdateDto>(dto);
            return _dataModel;
        }

        /// <summary>
        /// 读取Dto的数据模型 用于查看详情
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<VoloModelInfo> ReadDetailModel(int id)
        {
            var _info = await _dbContext.ServiceInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();
            if (_info == null || _info == default)
            {
                throw new PasteCodeException("查询的信息不存在，无法执行编辑操作！");
            }
            var dto = ObjectMapper.Map<ServiceInfo, ServiceInfoDto>(_info);
            var _dataModel = PasteBuilderHelper.ReadModelProperty<ServiceInfoDto>(dto);
            return _dataModel;
        }

        /// <summary>
        /// 读取ListDto的数据模型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public VoloModelInfo ReadListModel()
        {
            var _model = PasteBuilderHelper.ReadModelProperty<ServiceInfoListDto>(new ServiceInfoListDto());
            var _query_model = PasteBuilderHelper.ReadModelProperty(new InputSearchBase());
            if (_query_model != null)
            {
                _model.QueryProperties = _query_model.Properties;
            }
            return _model;
        }

        /// <summary>
        /// 按页获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<PagedResultDto<ServiceInfoListDto>> Page([FromQuery]InputSearchBase input)
        {
            var query = _dbContext.ServiceInfo.Where(t => 1 == 1).OrderByDescending(x=>x.Id);
            var _pagedto = new PagedResultDto<ServiceInfoListDto>();
            _pagedto.TotalCount = await query.CountAsync();
            var userList = await query.Page(input.page, input.size).ToListAsync();
            var temList = ObjectMapper.Map<List<ServiceInfo>, List<ServiceInfoListDto>>(userList);
            _pagedto.Items = temList;
            return _pagedto;
        }    }
}
